class Counter {
  private var value = 0

  /*
   改值器方法, 调用一般使用 ()
   */
  def increment() {
    value += 1
  }

  /*
   取值器方法, 调用一般不使用 ()
   */
  def current = value
}

class Person(val name: String) {
  private var privateAge = 0

  def age = privateAge

  def age_=(newValue: Int) {
    if (newValue > privateAge) {
      privateAge = newValue
    }
  }

  override def toString = getClass().getName() + "[name=" + name + "]"
}

// class Accounts {
//   val id = Accounts.newUniqueNumber
//   private var balance = 0.0

//   def deposit(amount: Double) {
//     balance += amount
//   }
// }

abstract class UndoableAction(val description: String) {
  def undo(): Unit

  def redo(): Unit
}

object DoNothingAction extends UndoableAction("Do nothing") {
  override def undo() {}

  override def redo() {}
}

class Account private (val id: Int, initialBalance: Double) {
  private var balance = initialBalance
}

object Account {
  private var lastNumber = 0

  def newUniqueNumber = {
    lastNumber += 1
    lastNumber
  }

  def apply(initialBalance: Double) = new Account(newUniqueNumber, initialBalance)
}

// object Hi {
//   def main(args: Array[String]) {
//     val myCounter = new Counter()
//     myCounter.increment()
//     println(myCounter.current)

//     val fred = new Person

//     fred.age = 21
//     fred.age = 20
//     println(fred.age)

//     // val account = new Accounts()
//     // println(account.id)

//     val actions = Map("open" -> DoNothingAction, "save" -> DoNothingAction)
//     println(actions)

//     val acct = Account(1000.0)
//     println(acct.id)
//   }
// }

// class Employee extends Person {
//   var salary = 0.0
//   val name = "Hello World"

//   override def toString = getClass.getName + "[name=" + name + "]"
// }

class SecretAgent(codename: String) extends Person(codename) {

  // override val name = "secret"
  override val toString = "secret"
}

object Hello extends App {
  val acct = Account(1000.0)
  println(acct.id)

  // val e = new Employee

  // if (e.isInstanceOf[Employee]) {
  //   val s = e.asInstanceOf[Employee]

  //   println(s)
  // }

  // e match {
  //   case s: Employee => println(s)
  //   case _ => println("s is not an Employee instance")
  // }

  val e = new SecretAgent("Yong")
  print(e.name)

}
